/**
 * @name 请求API代理
 * @author gongzhen
 * @param options
 * @param 参数详解：https://github.com/axios/axios
 * @since 2018-09-13
 */
import axios from "axios"
import errorHint from "./errorHint"
import loginUtil from "../login"
import { message } from "antd"
import qs from "qs"

// 默认配置
axios.defaults.method = "post"
axios.defaults.withCredentials = true
axios.defaults.headers.post["Content-Type"] = ""

const noNeedAuthAPI = ["/api/v1/captcha", "/api/v1/user/auth/captcha"]
/**
 * 正在进行（pending 状态）的请求记录
 */
// 记录所有正在进行（pending 状态）的请求的 "唯一值" 和 "取消请求方法"
const allPendingRequestsRecord = []
/**
 * 通过请求的 url 和 method 来标示请求唯一值
 * @param {*} config 配置信息
 * @returns
 */
function getUniqueId(config) {
  return `url=${config.url}&method=${config.method}`
}
/**
 * 取消请求，并移除记录
 * @param {*} config 配置信息
 */
function removePendingRequestRecord(config) {
  allPendingRequestsRecord.some((item, index) => {
    if (item.id === getUniqueId(config)) {
      // console.log('-- cancel id:', item.id)
      item.cancel() // 取消请求
      allPendingRequestsRecord.splice(index, 1) // 移除记录
      return true
    }
  })
  // console.log('-- allPendingRequestsRecord:', allPendingRequestsRecord.length, JSON.stringify(allPendingRequestsRecord))
}
/**
 * 取消所有请求并移除所有记录
 *
 * 页面切换时，取消所有请求并移除所有记录 useAge:
 *    import {removeAllPendingRequestsRecord} from './helper/axios';
 *    router.beforeEach((to, from, next) => {
 *      removeAllPendingRequestsRecord();
 *    }
 */
export function removeAllPendingRequestsRecord() {
  allPendingRequestsRecord.forEach((item) => {
    item.cancel("page changes") // 取消请求
  })
  allPendingRequestsRecord.splice(0) // 移除所有记录
}

// 添加请求拦截器
axios.interceptors.request.use(async (config) => {
  let newConfig = JSON.parse(JSON.stringify(config))
  if (process.env.API === "mock") {
    config.url = `http://rap2api.taobao.org/app/mock/226811/${config.method}${
      config.url
    }`
  } else {
    if (noNeedAuthAPI.indexOf(config.url) > -1) {
      return config
    }
    if (config.method === "get" && qs.stringify(config.data)) {
      config.url = config.url + "?" + qs.stringify(config.data)
    }

    const userInfo = loginUtil.getUserInfo()

    if (userInfo) {
      config.headers.common["token"] = userInfo.token
    } else {
      // window.location.href = '/login';
    }
  }

  // 通过添加随机 uniqueCancel 值，确保每个请求具有唯一标示
  // config.url = `${config.url}?uniqueCancel_${Math.random()
  //   .toString(36)
  //   .substr(2)}`

  // 在请求发送前执行一下取消操作，防止重复发送请求（dashboard 类似页面具有重复多次的相同请求，所有不能在全局做防止重复）
  await (config.method === "get" && removePendingRequestRecord(newConfig))

  // 设置请求的 cancelToken
  config.cancelToken = new axios.CancelToken(function executor(cancel) {
    // 添加记录，记录请求的唯一值和取消方法
    allPendingRequestsRecord.push({ id: getUniqueId(newConfig), cancel })
  })

  return config
})

axios.interceptors.response.use(
  (res) => {
    // 请求成功后移除记录
    removePendingRequestRecord(res.config)
    return res
  },
  (error) => {
    if (error.response) {
      switch (error.response.status) {
        case 401:
          // 返回 401 清除token信息并跳转到登录页面
          message.error("token过期")
          removeAllPendingRequestsRecord()
          location.href = location.origin + "/"
      }
    }
    return Promise.reject(error) // 返回接口返回的错误信息
  }
)

const request = (options, resolve) =>
  axios({ ...options })
    .then((resp) => {
      const data = resp.data || {}
      resolve(data)

      if (data.code !== 200 && options.handle === false) {
        errorHint.push(data.msg)
      }
    })
    .catch((err) => {
      if (err && err.message) {
        const data = {
          status: false,
          code: "-1",
          msg: `HTTP ERROR: ${err.message}`,
        }

        resolve(data)
        errorHint.push(data.msg)
      }
    })

const ajax = (options) => new Promise((resolve) => request(options, resolve))

export default ajax
